#include <stdio.h>

// bis用来设置位，规则是：当m的第i位为1时，x的第i位也要设置为1；
//                      当m的第i位为0时，x的第i位不变。
// bic用来清除位，规则是：当m的第i位为1时，x的第i位要设置为0；
//                      当m的第i位为0时，x的第i位不变。
// 这两个函数的实现都使用了位运算符。
int bis(int x, int m);
int bic(int x, int m);


// bis函数的实现
int bis(int x, int m) {
    return x | m;
}
// bic函数的实现
// 实现原理：可以想一下按位与的工作方式，当m的第i位为1时，
//          x的第i位要设置为0；当m的第i位为0时，x的第i位不变。
// 可以看到按位与运算和bic运算有两个一模一样的结果，即保留不变和强制为0，
// 不同的是，他的条件是相反的。所以我们可以将条件m取反，这样使用按位与操作就可以实现bic的功能了
int bic(int x, int m) {
    return x & ~m;
}
// 测试bis和bic函数
void test_bis_bic(int x, int m) {
    printf("x = 0x%x, m = 0x%x\n", x, m);
    printf("bis(x, m) = 0x%x\n", bis(x, m));
    printf("bic(x, m) = 0x%x\n", bic(x, m));
}

int bool_or(int x, int y) {
    // 用 bis 或者 bic 实现按位或操作
    return bis(x, y);
}
int bool_xor(int x, int y) {
    // 用 bis 或者 bic 实现按位异或操作
    // 异或的原理很简单：相同的位为0，不同的位为1
    // 整体理解：经过 bic(x,y) 后，相同的位都被清零了，这符合异或的要求；
    //          但是此时不同的位只筛选出了一部分，即x中为1，y中为0的部分；
    //          我们需要再找出x中为0，y中为1的部分，这个时候我们就可以用 bic(y,x) 来找出这部分位了。
    //          最后我们把这两部分相加就可以了。
    return bis(bic(x, y), bic(y, x));
}
int bool_and(int x, int y) {
    // 用 bis 或者 bic 实现按位与操作
    return bic(x, y);
}
int bool_not(int x) {
    // 用 bis 或者 bic 实现按位非操作
    return bic(x, 0xFFFFFFFF);
}
// 测试bool_or、bool_xor、bool_and和bool_not函数
void test_bool_operations(int x, int y) {
    printf("x = 0x%x, y = 0x%x\n", x, y);
    printf("bool_or(x, y) = 0x%x\n", bool_or(x, y));
    printf("bool_xor(x, y) = 0x%x\n", bool_xor(x, y));
    printf("bool_and(x, y) = 0x%x\n", bool_and(x, y));
    printf("bool_not(x) = 0x%x\n", bool_not(x));
}

// 自定义函数：打印整数的二进制表示
void print_binary(int num, int bits) {
    for (int i = bits - 1; i >= 0; i--) {
        printf("%d", (num >> i) & 1);
    }
}

int main() {
    int x = 0x12345678;
    int m = 0x000000FF;
    test_bis_bic(x, m);

    printf("y&~n 的效果：\n");
    int y = 0b11001100;
    int n = 0b11110000;
    // 打印 y 和 n 的二进制表示
    printf("y    = 0b");
    print_binary(y, 8);
    printf("\n");
    printf("n    = 0b");
    print_binary(n, 8);
    printf("\n");

    // 计算 y&n 的结果
    printf("y&n  = 0b");
    print_binary(y&n, 8);
    printf("\n");

    // 计算 y & ~n 并打印结果
    int result = y & ~n;
    printf("y&~n = 0b");
    print_binary(result, 8);
    printf("\n");

    // 计算 y|n 的结果
    printf("y|n  = 0b");
    print_binary(y|n, 8);
    printf("\n");
    printf("y|~n = 0b");
    print_binary(y|~n, 8);
    printf("\n");

    // 计算 y^n 的结果
    printf("y^n  = 0b");
    print_binary(y^n, 8);
    printf("\n");
    printf("y^~n = 0b");
    print_binary(y^~n, 8);
    printf("\n");

    return 0;
}
// Compile with: gcc -o bis_bic bis_bic.c
// Run with: ./bis_bic
// Output will show the results of bis and bic operations on x and m.
// The output will depend on the values of x and m.
// The bis function sets bits in x according to the mask m, while the bic
// function clears bits in x according to the mask m.
// The test_bis_bic function demonstrates the usage of bis and bic functions
// by printing the results of the operations.